home *** CD-ROM | disk | FTP | other *** search
/ Enter 2001 August / EnterCD8.iso / Internet / HTTrack Website Copier / httrack.exe / {app} / src / htsmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-03  |  64.5 KB  |  1,771 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       main routine (first called)                            */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. #include "htsmain.h"
  39.  
  40. #include "htsglobal.h"
  41. #include "httrack.h"
  42. #include "htsdefines.h"
  43. #include "htsalias.h"
  44. #include <ctype.h>
  45. #if HTS_WIN
  46. #else
  47. #ifndef HTS_DO_NOT_USE_UID
  48. /* setuid */
  49. #include <pwd.h>
  50. #include <unistd.h>
  51. #endif
  52. #endif
  53.  
  54. extern int exit_xh;          // sortir prΘmaturΘment
  55.  
  56. // Add a command in the argc/argv
  57. #define cmdl_add(token,argc,argv,buff,ptr) \
  58.   argv[argc]=(buff+ptr); \
  59.   strcpy(argv[argc],token); \
  60.   ptr += (strlen(argv[argc])+1); \
  61.   argc++
  62.  
  63. // Insert a command in the argc/argv
  64. #define cmdl_ins(token,argc,argv,buff,ptr) \
  65.   { \
  66.   int i; \
  67.   for(i=argc;i>0;i--)\
  68.   argv[i]=argv[i-1];\
  69.   } \
  70.   argv[0]=(buff+ptr); \
  71.   strcpy(argv[0],token); \
  72.   ptr += (strlen(argv[0])+1); \
  73.   argc++
  74.  
  75.  
  76. // Main, rΘcupΦre les paramΦtres et appelle le robot
  77. #if HTS_ANALYSTE!=2
  78. int main(int argc, char **argv) {
  79. #else
  80. int hts_main(int argc, char **argv) {
  81. #endif
  82.   char* x_argv[999];      // Patch pour argv et argc: en cas de rΘcupΘration de ligne de commande
  83.   char* x_argvblk=NULL;   // (reprise ou update)
  84.   int   x_ptr=0;          // offset
  85.   /*
  86.   char* x_argv2[999];     // Patch pour config
  87.   char* x_argvblk2=NULL;
  88.   */
  89.   //
  90.   int argv_url=-1;         // ==0 : utiliser cache et doit.log
  91.   char url[65536];         // URLS sΘparΘes par un espace
  92.   // the parametres
  93.   httrackp httrack;
  94.   int httrack_logmode=3;   // ONE log file
  95.   int recuperer=0;       // rΘcupΘrer un plantage (n'arrive jamais, α supprimer)
  96. #if HTS_WIN
  97. #if HTS_ANALYSTE!=2
  98.   WORD   wVersionRequested; /* requested version WinSock API */ 
  99.   WSADATA wsadata;        /* Windows Sockets API data */
  100. #endif
  101. #else
  102. #ifndef HTS_DO_NOT_USE_UID
  103.   int switch_uid=-1,switch_gid=-1;      /* setuid/setgid */
  104. #endif
  105.   int switch_chroot=0;                  /* chroot ? */
  106. #endif
  107.   //
  108.   url[0]='\0';
  109.   //
  110.  
  111.   // options par dΘfaut
  112.   bzero((char *)&httrack, sizeof(httrackp));
  113.   httrack.wizard=2;   // wizard automatique
  114.   httrack.quiet=0;     // questions
  115.   //  
  116.   httrack.travel=0;   // mΩme adresse
  117.   httrack.depth=9999; // mirror total par dΘfaut
  118.   httrack.extdepth=0; // mais pas α l'extΘrieur
  119.   httrack.seeker=1;   // down 
  120.   httrack.urlmode=2;  // relatif par dΘfaut
  121.   httrack.debug=0;    // pas de dΘbug en plus
  122.   httrack.getmode=3;  // linear scan
  123.   httrack.maxsite=-1; // taille max site (aucune)
  124.   httrack.maxfile_nonhtml=-1; // taille max fichier non html
  125.   httrack.maxfile_html=-1;    // idem pour html
  126.   httrack.maxsoc=8;     // nbre socket max
  127.   httrack.fragment=-1;  // pas de fragmentation
  128.   httrack.nearlink=0;   // ne pas prendre les liens non-html "adjacents"
  129.   httrack.makeindex=1;  // faire un index
  130.   httrack.kindex=0;     // index 'keyword'
  131.   httrack.delete_old=1; // effacer anciens fichiers
  132.   httrack.makestat=0;  // pas de fichier de stats
  133.   httrack.maketrack=0; // ni de tracking
  134.   httrack.timeout=120; // timeout par dΘfaut (2 minutes)
  135.   httrack.cache=1;     // cache prioritaire
  136.   httrack.shell=0;     // pas de shell par defaut
  137.   httrack.proxy.active=0;    // pas de proxy
  138.   httrack.user_agent_send=1; // envoyer un user-agent
  139.   strcpy(httrack.user_agent,"Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)");
  140.   httrack.savename_83=0;     // noms longs par dΘfaut
  141.   httrack.savename_type=0;   // avec structure originale
  142.   httrack.parsejava=1;       // parser classes
  143.   httrack.hostcontrol=0;     // PAS de control host pour timeout et traffic jammer
  144.   httrack.retry=2;           // 2 retry par dΘfaut
  145.   httrack.errpage=1;         // copier ou gΘnΘrer une page d'erreur en cas d'erreur (404 etc.)
  146.   httrack.check_type=1;      // vΘrifier type si inconnu (cgi,asp..) SAUF / considΘrΘ comme html
  147.   httrack.all_in_cache=0;    // ne pas tout stocker en cache
  148.   httrack.robots=2;          // traiter les robots.txt
  149.   httrack.external=0;        // liens externes normaux
  150.   httrack.passprivacy=0;     // mots de passe dans les fichiers
  151.   httrack.mirror_first_page=0;  // pas mode mirror links
  152.   httrack.accept_cookie=1;   // gΘrer les cookies
  153.   httrack.cookie=NULL;
  154.   httrack.http10=0;          // laisser http/1.1
  155.   httrack.tolerant=0;        // ne pas accepter content-length incorrect
  156.   httrack.parseall=1;        // tout parser (tags inconnus, par exemple)
  157.   httrack.norecatch=0;       // ne pas reprendre les fichiers effacΘs par l'utilisateur
  158.   httrack.verbosedisplay=0;  // pas d'animation texte
  159.   strcpy(httrack.footer,HTS_DEFAULT_FOOTER);
  160.   httrack.ftp_proxy=1;       // proxy http pour ftp
  161.   strcpy(httrack.filelist,"");
  162.   strcpy(httrack.lang_iso,"en, *");
  163.   //
  164.   httrack.log=stdout;
  165.   httrack.errlog=stderr;
  166.   httrack.flush=1;           // flush sur les fichiers log
  167.   httrack.aff_progress=0;
  168.   httrack.keyboard=0;
  169.   //
  170.   strcpy(httrack.path_html,"");
  171.   strcpy(httrack.path_log,"");
  172.   //
  173.   httrack.maxlink=100000;    // 100,000 liens max par dΘfaut (400Kb)
  174.   httrack.maxfilter=500;     // 500 filtres max par dΘfaut (400Kb)
  175.   httrack.maxcache=1048576*32;   // a peu prΦs 32Mo en cache max -- OPTION NON PARAMETRABLE POUR L'INSTANT --
  176.   //httrack.maxcache_anticipate=256;  // maximum de liens α anticiper
  177.   httrack.maxtime=-1;        // temps max en secondes
  178.   httrack.maxrate=-1;        // pas de taux maxi
  179.   httrack.maxconn=10;        // nombre connexions/s
  180.   httrack.waittime=-1;      // wait until.. hh*3600+mm*60+ss
  181.   //
  182.   httrack.exec=argv[0];
  183.   //
  184.   _DEBUG_HEAD=0;            // pas de debuggage en tΩtes
  185.   
  186. #if HTS_WIN
  187. #if HTS_ANALYSTE!=2
  188.   {
  189.     int stat;
  190.     wVersionRequested = 0x0101;
  191.     stat = WSAStartup( wVersionRequested, &wsadata );
  192.     if (stat != 0) {
  193.       HTS_PANIC_PRINTF("Winsock not found!\n");
  194.       return -1;
  195.     } else if (LOBYTE(wsadata.wVersion) != 1  && HIBYTE(wsadata.wVersion) != 1) {
  196.       HTS_PANIC_PRINTF("WINSOCK.DLL does not support version 1.1\n");
  197.       WSACleanup();
  198.       return -1;
  199.     }
  200.   }
  201. #endif
  202. #endif
  203.  
  204.   /* First test: if -#R then only launch ftp */
  205.   if (argc > 2) {
  206.     if (strcmp(argv[1],"-#R")==0) {
  207.       if (argc==6) {
  208.         lien_back r;
  209.         char* path;
  210.         FILE* fp;
  211.         strcpy(r.url_adr,argv[2]);
  212.         strcpy(r.url_fil,argv[3]);
  213.         strcpy(r.url_sav,argv[4]);
  214.         path=argv[5];
  215.         r.status=1000;
  216.         run_launch_ftp(&r);
  217.         fp=fopen(fconv(path),"wb");
  218.         if (fp) {
  219.           fprintf(fp,"%d %s",r.r.statuscode,r.r.msg);
  220.           fclose(fp); fp=NULL;
  221.           rename(fconv(path),fconcat(path,".ok"));
  222.         } else remove(fconv(path));
  223.       } else {
  224.         printf("htsftp error, wrong parameter number (%d)\n",argc);
  225.       }
  226.       exit(0);   // pas _exit()
  227.     }
  228.   }
  229.  
  230.   // ok, non ftp, continuer
  231.  
  232.  
  233.   /* filter CR, LF, TAB.. */
  234.   {
  235.     int na;
  236.     for(na=1;na<argc;na++) {
  237.       char* a;
  238.       while( (a=strchr(argv[na],'\x0d')) ) *a=' ';
  239.       while( (a=strchr(argv[na],'\x0a')) ) *a=' ';
  240.       while( (a=strchr(argv[na],9)) )      *a=' ';
  241.       /* equivalent to "empty parameter" */
  242.       if ((strcmp(argv[na],HTS_NOPARAM)==0) || (strcmp(argv[na],HTS_NOPARAM2)==0))        // (none)
  243.         strcpy(argv[na],"\"\"");
  244.       if (strncmp(argv[na],"-&",2)==0)
  245.         argv[na][1]='%';
  246.     }
  247.   }
  248.  
  249.  
  250.  
  251.   /* create x_argvblk buffer for transformed command line */
  252.   {
  253.     int current_size=0;
  254.     int size;
  255.     int na;
  256.     for(na=0;na<argc;na++)
  257.       current_size += (strlen(argv[na]) + 1);
  258.     if ((size=fsize("config"))>0)
  259.       current_size += size;
  260.     x_argvblk=(char*) malloct(current_size+32768);
  261.     if (x_argvblk == NULL) {
  262.       HTS_PANIC_PRINTF("Error, not enough memory");
  263.       return -1;
  264.     }
  265.     x_argvblk[0]='\0';
  266.     x_ptr=0;
  267.   }
  268.  
  269.   /* Create new argc/argv, replace alias, count URLs, treat -h, -q, -i */
  270.   {
  271.     char _tmp_argv[2][HTS_CDLMAXSIZE];
  272.     char* tmp_argv[2];
  273.     char tmp_error[HTS_CDLMAXSIZE];
  274.     int tmp_argc;
  275.     int x_argc=0;
  276.     int na;
  277.     tmp_argv[0]=_tmp_argv[0];
  278.     tmp_argv[1]=_tmp_argv[1];
  279.     //
  280.     argv_url=0;       /* pour comptage */
  281.     //
  282.     cmdl_add(argv[0],x_argc,x_argv,x_argvblk,x_ptr);
  283.     na=1;             /* commencer aprΦs nom_prg */
  284.     while(na<argc) {
  285.       int result=1;
  286.       tmp_argv[0][0]=tmp_argv[1][0]='\0';
  287.  
  288.       /* VΘrifier argv[] non vide */
  289.       if (strnotempty(argv[na])) {
  290.         
  291.         /* VΘrifier Commande (alias) */
  292.         result=optalias_check(argc,(const char * const *)argv,na,
  293.           &tmp_argc,(char**)tmp_argv,tmp_error);
  294.         if (!result) {
  295.           HTS_PANIC_PRINTF(tmp_error);
  296.           return -1;
  297.         }
  298.         
  299.         /* Copier */
  300.         cmdl_add(tmp_argv[0],x_argc,x_argv,x_argvblk,x_ptr);
  301.         if (tmp_argc > 1) {
  302.           cmdl_add(tmp_argv[1],x_argc,x_argv,x_argvblk,x_ptr);
  303.         }
  304.         
  305.         /* Compter URLs et dΘtecter -i,-q.. */
  306.         if (tmp_argc == 1) {           /* pas -P & co */
  307.           if (!cmdl_opt(tmp_argv[0])) {   /* pas -c0 & co */
  308.             if (argv_url>=0)
  309.               argv_url++;
  310.           } else {
  311.             if (strcmp(tmp_argv[0],"-h")==0) {
  312.               help(argv[0],!httrack.quiet);
  313.               return 0;
  314.             } else {
  315.               if (strncmp(tmp_argv[0],"--",2)) {   /* pas */
  316.                 if ((strchr(tmp_argv[0],'q')!=NULL))
  317.                   httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  318.                 if ((strchr(tmp_argv[0],'i')!=NULL)) {  // doit.log!
  319.                   argv_url=-1;        /* forcer */
  320.                   httrack.quiet=1;
  321.                 }
  322.               }
  323.             }
  324.           }
  325.         } else if (tmp_argc == 2) {
  326.           if ((strcmp(tmp_argv[0],"-%L")==0)) {  // liste d'URLs
  327.             if (argv_url>=0)
  328.               argv_url++;        /* forcer */
  329.           }
  330.         }
  331.       }
  332.  
  333.       na+=result;
  334.     }
  335.     if (argv_url<0)
  336.       argv_url=0;
  337.  
  338.     /* Nouveaux argc et argv */
  339.     argv=x_argv;
  340.     argc=x_argc;
  341.   }
  342.  
  343.  
  344.  
  345.  
  346.   // Ici on ajoute les arguments de config
  347. /*
  348.   if (fexist("config")) {    // configuration        
  349.     x_argvblk2=(char*) calloct(32768,1);
  350.  
  351.     if (x_argvblk2!=NULL) {
  352.       FILE* fp;
  353.       int x_argc2;
  354.           
  355.       //strcpy(x_argvblk2,"httrack ");
  356.       fp=fopen("config","rb");
  357.       if (fp) {
  358.         linput(fp,x_argvblk2+strlen(x_argvblk2),32000);
  359.         fclose(fp); fp=NULL;
  360.     
  361.         // calculer arguments selon derniers arguments
  362.         x_argv2[0]=argv[0];
  363.         x_argc2=1;
  364.         {
  365.           char* p=x_argvblk2;
  366.           do {
  367.             x_argv2[x_argc2++]=p;
  368.             p=strchr(p,' ');
  369.             if (p) {
  370.               *p=0;    // octet nul (tableau)
  371.               p++;
  372.             }            
  373.           } while(p!=NULL);
  374.         }
  375.         // recopier arguments actuels (pointeurs uniquement)
  376.         {
  377.          int na;
  378.           for(na=1;na<argc;na++) {
  379.             x_argv2[x_argc2++]=argv[na];
  380.           }
  381.         }
  382.         argc=x_argc2;      // nouvel argc
  383.         argv=x_argv2;      // nouvel argv
  384.       }
  385.     }
  386.   }
  387. */
  388.  
  389.  
  390.   // Traiter l'option -O en premier!
  391.   { 
  392.     char* com;
  393.     int na;
  394.     
  395.     for(na=1;na<argc;na++) {
  396.       
  397.       if (argv[na][0]=='"') {
  398.         char tempo[HTS_CDLMAXSIZE];
  399.         strcpy(tempo,argv[na]+1);
  400.         if (tempo[strlen(tempo)-1]!='"') {
  401.           char s[HTS_CDLMAXSIZE];
  402.           sprintf(s,"Missing quote in %s",argv[na]);
  403.           HTS_PANIC_PRINTF(s);
  404.           return -1;
  405.         }
  406.         tempo[strlen(tempo)-1]='\0';
  407.         strcpy(argv[na],tempo);
  408.       }
  409.       
  410.       if (cmdl_opt(argv[na])) { // option
  411.         com=argv[na]+1;
  412.         
  413.         while(*com) {
  414.           switch(*com) {
  415.           case 'O':    // output path
  416.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  417.               HTS_PANIC_PRINTF("Option O needs to be followed by a blank space, and a path (or path,path)");
  418.               printf("Example: -O /binary/\n");
  419.               printf("Example: -O /binary/,/log/\n");
  420.               return -1;
  421.             } else {
  422.               char* a;
  423.               na++;
  424.               strcpy(httrack.path_html,"");
  425.               strcpy(httrack.path_log,"");
  426.               a=strstr(argv[na],"\",\"");  // rechercher en premier, au cas ou -O "c:\pipo,test","c:\test"
  427.               if (!a)
  428.                 a=strchr(argv[na],',');  // 2 path
  429.               else
  430.                 a++;  // position ,
  431.               if (a) {
  432.                 strncat(httrack.path_html,argv[na],(int) a-(int) argv[na]);
  433.                 strcat(httrack.path_log,a+1);
  434.               } else {
  435.                 strcpy(httrack.path_log,argv[na]);
  436.                 strcpy(httrack.path_html,argv[na]);
  437.               }
  438.               // Eliminer les cas comme -O "C:\mirror\"
  439.               if (httrack.path_log[0]=='"') {  // Guillemets
  440.                 char tmp[256];
  441.                 strcpy(tmp,httrack.path_log+1);
  442.                 if (tmp[strlen(tmp)-1]=='"')
  443.                   tmp[strlen(tmp)-1]='\0';
  444.                 strcpy(httrack.path_log,tmp);
  445.               }
  446.               if (httrack.path_html[0]=='"') {
  447.                 char tmp[256];
  448.                 strcpy(tmp,httrack.path_html+1);
  449.                 if (tmp[strlen(tmp)-1]=='"')
  450.                   tmp[strlen(tmp)-1]='\0';
  451.                 strcpy(httrack.path_html,tmp);
  452.               }
  453.               check_path(httrack.path_log);
  454.               check_path(httrack.path_html);
  455.               
  456.               //printf("-->%s\n%s\n",httrack.path_html,httrack.path_log);
  457.               
  458.             }
  459.             break;
  460.           }  // switch
  461.           com++;    
  462.         }  // while
  463.         
  464.       }  // arg
  465.       
  466.     }  // for
  467.   }  // traiter -O
  468.   
  469.   /* if doit.log exists, or if new URL(s) defined, 
  470.      then DO NOT load standard config files */
  471.   /* (config files are added in doit.log) */
  472. #if DEBUG_STEPS
  473.   printf("Loading httrackrc/doit.log\n");
  474. #endif
  475.   /* recreate a doit.log (no old doit.log or new URLs (and parameters)) */
  476.   if ( (!fexist(fconcat(httrack.path_log,"hts-cache/doit.log"))) || (argv_url>0) ) {
  477.     if (!optinclude_file(fconcat(httrack.path_log,HTS_HTTRACKRC),&argc,argv,x_argvblk,&x_ptr))
  478.       if (!optinclude_file(HTS_HTTRACKRC,&argc,argv,x_argvblk,&x_ptr)) {
  479.         if (!optinclude_file(fconcat(hts_gethome(),"/"HTS_HTTRACKRC),&argc,argv,x_argvblk,&x_ptr)) {
  480. #ifdef HTS_HTTRACKCNF
  481.           optinclude_file(HTS_HTTRACKCNF,&argc,argv,x_argvblk,&x_ptr);
  482. #endif
  483.         }
  484.       }
  485.   } 
  486.   /* load doit.log and insert in current command line */
  487.   else {
  488.     FILE* fp=fopen(fconcat(httrack.path_log,"hts-cache/doit.log"),"rb");
  489.     if (fp) {
  490.       int insert_after=1;     /* insΘrer aprΦs nom au dΘbut */
  491.       //
  492.       char buff[8192];
  493.       char *p,*lastp;
  494.       linput(fp,buff,8000);
  495.       fclose(fp); fp=NULL;
  496.       p=buff;
  497.       do {
  498.         int insert_after_argc;
  499.         // read next
  500.         lastp=p;
  501.         if (p) {
  502.           p=next_token(p,1);
  503.           if (p) {
  504.             *p=0;    // null
  505.             p++;
  506.           }
  507.         }
  508.  
  509.         /* Insert parameters BUT so that they can be in the same order */
  510.         if (lastp) {
  511.           if (strnotempty(lastp)) {
  512.             insert_after_argc=argc-insert_after;
  513.             cmdl_ins(lastp,insert_after_argc,(argv+insert_after),x_argvblk,x_ptr);
  514.             argc=insert_after_argc+insert_after;
  515.             insert_after++;
  516.           }
  517.         }
  518.       } while(lastp!=NULL);
  519.       //fclose(fp);
  520.     }
  521.   }
  522.  
  523.  
  524.   // Existence d'un cache - pas de new mais un old.. renommer
  525. #if DEBUG_STEPS
  526.   printf("Checking cache\n");
  527. #endif
  528.   if ( (!fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) || (!fexist(fconcat(httrack.path_log,"hts-cache/new.ndx"))) ) {
  529.     if ( (fexist(fconcat(httrack.path_log,"hts-cache/old.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/old.ndx"))) ) {
  530.       remove(fconcat(httrack.path_log,"hts-cache/new.dat"));
  531.       remove(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  532.       //remove(fconcat(httrack.path_log,"hts-cache/new.lst"));
  533.       rename(fconcat(httrack.path_log,"hts-cache/old.dat"),fconcat(httrack.path_log,"hts-cache/new.dat"));
  534.       rename(fconcat(httrack.path_log,"hts-cache/old.ndx"),fconcat(httrack.path_log,"hts-cache/new.ndx"));
  535.       //rename(fconcat(httrack.path_log,"hts-cache/old.lst"),fconcat(httrack.path_log,"hts-cache/new.lst"));
  536.     }
  537.   }
  538.  
  539.   /* Interrupted mirror detected */
  540.   if (!httrack.quiet) {
  541.     if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {
  542.       /* Old cache */
  543.       if ( (fexist(fconcat(httrack.path_log,"hts-cache/old.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/old.ndx"))) ) {
  544.         fprintf(httrack.log,"Warning!\n");
  545.         fprintf(httrack.log,"An aborted mirror has been detected!\nThe current temporary cache is required for any update operation and only contains data downloaded during the last aborted session.\nThe former cache might contain more complete information; if you do not want to lose that information, you have to restore it and delete the current cache.\nThis can easily be done here by erasing the hts-cache/new.* files\n");
  546.         fprintf(httrack.log,"Please restart HTTrack with --quiet (-q) option to override this message!\n");
  547.         exit(0);
  548.       }
  549.     }
  550.   }
  551.     
  552.   // remplacer "macros" comme --spider
  553.   // permet de lancer httrack sans a avoir α se rappeler de syntaxes comme p0C0I0Qc32 ..
  554. #if DEBUG_STEPS
  555.   printf("Checking last macros\n");
  556. #endif
  557.   {
  558.     int i;
  559.     for(i=0;i<argc;i++) {
  560. #if DEBUG_STEPS
  561.       printf("Checking #%d:\n",argv[i]);
  562.       printf("%s\n",argv[i]);
  563. #endif
  564.       if (argv[i][0]=='-') {
  565.         if (argv[i][1]=='-') {  // --xxx
  566.           // Note: on fait attention α ne pas Θcrire plus qu'il n'y avait avant..
  567.           /*
  568.           if (strfield2(argv[i]+2,"spider"))       // mode spider (scan+log)
  569.             strcpy(argv[i]+1,"p0C0I0t");
  570.           else if (strfield2(argv[i]+2,"wide-spider"))   // spider
  571.             strcpy(argv[i]+1,"p0C0I0c32t");
  572.           else if (strfield2(argv[i]+2,"tiny-spider"))   // i am a little grasshoper
  573.             strcpy(argv[i]+1,"p0C0I0c1t");
  574.           else if (strfield2(argv[i]+2,"testsite"))       // mode test site (scan+log)
  575.             strcpy(argv[i]+1,"p0C0I0t");
  576.           else if (strfield2(argv[i]+2,"wide-testsite"))
  577.             strcpy(argv[i]+1,"p0C0I0c32t");
  578.           else if (strfield2(argv[i]+2,"tiny-testsite"))
  579.             strcpy(argv[i]+1,"p0C0I0c1t");
  580.           //
  581.           else if (strfield2(argv[i]+2,"testlinks"))       // mode test bookmark (scan+log)
  582.             strcpy(argv[i]+1,"r1p0C0I0t");
  583.           else if (strfield2(argv[i]+2,"wide-testlinks"))
  584.             strcpy(argv[i]+1,"r1p0C0I0c32t");
  585.           else if (strfield2(argv[i]+2,"tiny-testlinks"))
  586.             strcpy(argv[i]+1,"r1p0C0I0c1t");
  587.           else if ( (strfield2(argv[i]+2,"testlink")) || (strfield2(argv[i]+2,"bookmark"))) {
  588.             HTS_PANIC_PRINTF("Please use --testlinks to check links in a page");
  589.             return -1;                
  590.           }
  591.           //
  592.           else if (strfield2(argv[i]+2,"mirrorlinks"))       // mode test bookmark (scan+log)
  593.             strcpy(argv[i]+1,"Y");
  594.           else if (strfield2(argv[i]+2,"wide-mirrorlinks"))       // mode test bookmark (scan+log)
  595.             strcpy(argv[i]+1,"Yc32");
  596.           else if (strfield2(argv[i]+2,"tiny-mirrorlinks"))       // mode test bookmark (scan+log)
  597.             strcpy(argv[i]+1,"Yc1");
  598.           //
  599.           else if (strfield2(argv[i]+2,"mirror"))  // miroir (mode par dΘfaut)
  600.             strcpy(argv[i]+1,"");
  601.           else if (strfield2(argv[i]+2,"wide-mirror"))
  602.             strcpy(argv[i]+1,"c32");
  603.           else if (strfield2(argv[i]+2,"tiny-mirror"))
  604.             strcpy(argv[i]+1,"c1");
  605.           //
  606.           else if (strfield2(argv[i]+2,"testscan"))  // scan sans log
  607.             strcpy(argv[i]+1,"p0C0I0Q");
  608.           else if (strfield2(argv[i]+2,"wide-testscan"))
  609.             strcpy(argv[i]+1,"p0C0I0c32Q");
  610.           else if (strfield2(argv[i]+2,"tiny-testscan"))
  611.             strcpy(argv[i]+1,"p0C0I0c1Q");
  612.           else if ((strfield2(argv[i]+2,"scan")) || (strfield2(argv[i]+2,"test")) || (strfield2(argv[i]+2,"check"))) {
  613.             HTS_PANIC_PRINTF("Please use --spider to check all links in a site");
  614.             return -1;    
  615.           }
  616.           //
  617.           else if (strfield2(argv[i]+2,"skeleton"))    // rΘcupΘrer squelette (html)
  618.             strcpy(argv[i]+1,"p1");
  619.           else if (strfield2(argv[i]+2,"wide-skeleton"))
  620.             strcpy(argv[i]+1,"p1c32");
  621.           else if (strfield2(argv[i]+2,"tiny-skeleton"))
  622.             strcpy(argv[i]+1,"p1c1");
  623.           //
  624.           else if (strfield2(argv[i]+2,"get"))     // rΘcupΘrer fichiers isolΘs
  625.             strcpy(argv[i]+1,"qg");
  626.           else if (strfield2(argv[i]+2,"update"))        // update: pas de question
  627.             strcpy(argv[i]+1,"iC2");
  628.           else if (strfield2(argv[i]+2,"continue"))      // continue, cache prio
  629.             strcpy(argv[i]+1,"iC1");
  630.           else if (strfield2(argv[i]+2,"restart"))       // idem
  631.             strcpy(argv[i]+1,"iC1");
  632.           //
  633.           else if (strfield2(argv[i]+2,"sucker"))        // web sucker...toi aussi suce le web!
  634.             strcpy(argv[i]+1,"r99");
  635.     //
  636.           else if (strfield2(argv[i]+2,"help"))          // un peu d'aide
  637.             strcpy(argv[i]+1,"h");
  638.           else if (strfield2(argv[i]+2,"documentation"))
  639.             strcpy(argv[i]+1,"h");
  640.           else if (strfield2(argv[i]+2,"doc"))
  641.             strcpy(argv[i]+1,"h");
  642.           //
  643.           else if (strfield2(argv[i]+2,"wide"))
  644.             strcpy(argv[i]+1,"c32");
  645.           else if (strfield2(argv[i]+2,"tiny"))
  646.             strcpy(argv[i]+1,"c1");
  647.           else if (strfield2(argv[i]+2,"ultrawide"))  // oulαα..
  648.             strcpy(argv[i]+1,"c48");
  649.           //
  650.           else if (strfield2(argv[i]+2,"http10"))     // use if possible HTTP/1.0
  651.             strcpy(argv[i]+1,"%h");
  652.           //
  653.           else if ( (strfield2(argv[i]+2,"filelist"))     // file list
  654.                   || (strfield2(argv[i]+2,"list")) )
  655.             strcpy(argv[i]+1,"%L");
  656.  
  657.           else */
  658.           if ((strfield2(argv[i]+2,"clean")) || (strfield2(argv[i]+2,"tide"))) {  // nettoyer
  659.             strcpy(argv[i]+1,"");
  660.             if (fexist(fconcat(httrack.path_log,"hts-log.txt")))
  661.               remove(fconcat(httrack.path_log,"hts-log.txt"));
  662.             if (fexist(fconcat(httrack.path_log,"hts-err.txt")))
  663.               remove(fconcat(httrack.path_log,"hts-err.txt"));
  664.             if (fexist(fconcat(httrack.path_html,"index.html")))
  665.               remove(fconcat(httrack.path_html,"index.html"));
  666.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.dat")))
  667.               remove(fconcat(httrack.path_log,"hts-cache/new.dat"));
  668.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))
  669.               remove(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  670.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.dat")))
  671.               remove(fconcat(httrack.path_log,"hts-cache/old.dat"));
  672.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.ndx")))
  673.               remove(fconcat(httrack.path_log,"hts-cache/old.ndx"));
  674.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.lst")))
  675.               remove(fconcat(httrack.path_log,"hts-cache/new.lst"));
  676.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.lst")))
  677.               remove(fconcat(httrack.path_log,"hts-cache/old.lst"));
  678.             if (fexist(fconcat(httrack.path_log,"hts-cache/doit.log")))
  679.               remove(fconcat(httrack.path_log,"hts-cache/doit.log"));
  680.             if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock")))
  681.               remove(fconcat(httrack.path_log,"hts-in_progress.lock"));
  682.             rmdir(fconcat(httrack.path_log,"hts-cache"));
  683.             //
  684.           } else if (strfield2(argv[i]+2,"catchurl")) {      // capture d'URL via proxy temporaire!
  685.             argv_url=1;     // forcer a passer les parametres
  686.             strcpy(argv[i]+1,"#P");
  687.             //
  688.           } else if (strfield2(argv[i]+2,"updatehttrack")) {
  689. #ifdef _WIN32
  690.             char s[HTS_CDLMAXSIZE];
  691.             sprintf(s,"%s not available in this version",argv[i]);
  692.             HTS_PANIC_PRINTF(s);
  693.             return -1;
  694. #else
  695. #if 0
  696.             char _args[8][256];
  697.             char *args[8];
  698.             
  699.             printf("Cheking for updates...\n");
  700.             strcpy(_args[0],argv[0]);
  701.             strcpy(_args[1],"--get");
  702.             sprintf(_args[2],HTS_UPDATE_WEBSITE,HTS_PLATFORM,"");
  703.             strcpy(_args[3],"--quickinfo");
  704.             args[0]=_args[0];
  705.             args[1]=_args[1];
  706.             args[2]=_args[2];
  707.             args[3]=_args[3];
  708.             args[4]=NULL;
  709.             if (execvp(args[0],args)==-1) {
  710.             }
  711. #endif
  712. #endif
  713.           }
  714.           //
  715.           else {
  716.             char s[HTS_CDLMAXSIZE];
  717.             sprintf(s,"%s not recognized",argv[i]);
  718.             HTS_PANIC_PRINTF(s);
  719.             return -1;
  720.           }
  721.  
  722.         } 
  723.       }
  724.     }
  725.   }
  726.  
  727.   // Compter urls/jokers
  728.   /*
  729.   if (argv_url<=0) { 
  730.     int na;
  731.     argv_url=0;
  732.     for(na=1;na<argc;na++) {
  733.       if ( (strcmp(argv[na],"-P")==0) || (strcmp(argv[na],"-N")==0) || (strcmp(argv[na],"-F")==0) || (strcmp(argv[na],"-O")==0) || (strcmp(argv[na],"-V")==0) ) {
  734.         na++;    // sauter nom de proxy
  735.       } else if (!cmdl_opt(argv[na])) { 
  736.         argv_url++;   // un de plus       
  737.       } else if (strcmp(argv[na],"-h")==0) {
  738.         help(argv[0],!httrack.quiet);
  739.         return 0;
  740.       } else {
  741.         if ((strchr(argv[na],'q')!=NULL))
  742.           httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  743.         if ((strchr(argv[na],'i')!=NULL)) {  // doit.log!
  744.           argv_url=0;
  745.           na=argc;
  746.         }
  747.       }
  748.     }
  749.   }  
  750.   */
  751.  
  752.   // Ici on ajoute les arguments qui ont ΘtΘ appelΘs avant au cas o∙ on rΘcupΦre une session
  753.   // Exemple: httrack www.truc.fr -L0 puis ^C puis httrack sans URL : ajouter URL prΘcΘdente
  754.   /*
  755.   if (argv_url==0) {
  756.     //if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  757.     if (fexist(fconcat(httrack.path_log,"hts-cache/doit.log"))) {    // un cache est prΘsent
  758.       
  759.       x_argvblk=(char*) calloct(32768,1);
  760.       
  761.       if (x_argvblk!=NULL) {
  762.         FILE* fp;
  763.         int x_argc;
  764.         
  765.         //strcpy(x_argvblk,"httrack ");
  766.         fp=fopen(fconcat(httrack.path_log,"hts-cache/doit.log"),"rb");
  767.         if (fp) {
  768.           linput(fp,x_argvblk+strlen(x_argvblk),8192);
  769.           fclose(fp); fp=NULL;
  770.         }
  771.         
  772.         // calculer arguments selon derniers arguments
  773.         x_argv[0]=argv[0];
  774.         x_argc=1;
  775.         {
  776.           char* p=x_argvblk;
  777.           do {
  778.             x_argv[x_argc++]=p;
  779.             //p=strstr(p," ");
  780.             // exemple de chaine: "echo \"test\"" c:\a "\$0"
  781.             p=next_token(p,1);    // prochain token
  782.             if (p) {
  783.               *p=0;    // octet nul (tableau)
  784.               p++;
  785.             }            
  786.           } while(p!=NULL);
  787.         }
  788.         // recopier arguments actuels (pointeurs uniquement)
  789.         {
  790.           int na;
  791.           for(na=1;na<argc;na++) {
  792.             if (strcmp(argv[na],"-O") != 0)    // SAUF le path!
  793.               x_argv[x_argc++]=argv[na];
  794.             else
  795.               na++;
  796.           }
  797.         }
  798.         argc=x_argc;      // nouvel argc
  799.         argv=x_argv;      // nouvel argv
  800.       }
  801.       
  802.       
  803.     }
  804.     //}
  805.   }
  806.   */
  807.   
  808.   // VΘrifier quiet
  809.   /*
  810.   { 
  811.     int na;    
  812.     for(na=1;na<argc;na++) {
  813.       if (!cmdl_opt(argv[na])) { 
  814.         if ((strcmp(argv[na],"-P")==0) || (strcmp(argv[na],"-N")==0) || (strcmp(argv[na],"-F")==0) || (strcmp(argv[na],"-O")==0) || (strcmp(argv[na],"-V")==0))
  815.           na++;    // sauter nom de proxy
  816.       } else {
  817.         if ((strchr(argv[na],'q')!=NULL) || (strchr(argv[na],'i')!=NULL))
  818.           httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  819.       }
  820.     }
  821.   }
  822.   */
  823.  
  824.   // Pas d'URL
  825. #if DEBUG_STEPS
  826.   printf("Checking URLs\n");
  827. #endif
  828.   if (argv_url==0) {
  829.     // PrΘsence d'un cache, que faire?..
  830.     if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  831.       if (fexist(fconcat(httrack.path_log,"hts-cache/doit.log"))) {    // un cache est prΘsent
  832.         if (x_argvblk!=NULL) {
  833.           int m;        
  834.           // Θtablir mode - mode cache: 1 (cache valide) 2 (cache α vΘrifier)
  835.           if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {    // cache prioritaire
  836.             m=1;
  837.             recuperer=1;
  838.           } else {
  839.             m=2;
  840.           }
  841.           httrack.cache=m;
  842.           
  843.           if (httrack.quiet==0) {  // sinon on continue automatiquement
  844.             HT_REQUEST_START;
  845.             HT_PRINT("A cache has been found"LF);
  846.             if (m==1) {
  847.               HT_PRINT("That means that a transfer has been aborted"LF);
  848.               HT_PRINT("OK to Continue ");
  849.             } else {
  850.               HT_PRINT("That means you can update faster the remote site(s)"LF);
  851.               HT_PRINT("OK to Update ");
  852.             }
  853.             HT_PRINT("httrack "); HT_PRINT(x_argvblk); HT_PRINT("?"LF);
  854.             HT_REQUEST_END;
  855.             if (!ask_continue()) return 0;
  856.           }
  857.           
  858.         } else {
  859.           HTS_PANIC_PRINTF("Error, not enough memory");
  860.           return -1;
  861.         }
  862.       } else { // log existe pas
  863.         HTS_PANIC_PRINTF("A cache has been found, but no command line");
  864.         printf("Please launch httrack with proper parameters to reuse the cache\n");
  865.         return -1;
  866.       }
  867.       
  868.     } else {    // aucune URL dΘfinie et pas de cache
  869. #if HTS_ANALYSTE!=2
  870.       if (httrack.quiet) {
  871. #endif
  872.         help(argv[0],!httrack.quiet);
  873.         return -1;
  874. #if HTS_ANALYSTE!=2
  875.       } else {
  876.         help_wizard(&httrack);
  877.         return -1;
  878.       }
  879. #endif
  880.       return 0;
  881.     }
  882.   } else {   // plus de 2 paramΦtres
  883.     // un fichier log existe?
  884.     if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {  // fichier lock?
  885.       //char s[32];
  886.       
  887.       httrack.cache=1;    // cache prioritaire
  888.       if (httrack.quiet==0) {
  889.         if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  890.           HT_REQUEST_START;
  891.           HT_PRINT("There is a lock-file in the current directory"LF);
  892.           HT_PRINT("That means that a mirror has not been terminated"LF);
  893.           HT_PRINT("Be sure you call httrack with proper parameters"LF);
  894.           HT_PRINT("(The cache allows you to restart faster the transfer)"LF);
  895.           HT_REQUEST_END;
  896.           if (!ask_continue()) return 0;
  897.         /*} else {
  898.           HT_PRINT("There is a lock-file in the current directory"LF);
  899.           HT_PRINT("That means that a mirror has not been terminated"LF);
  900.           HT_PRINT("There is no cache, HTtrack will not be able to use formerly loaded files"LF);*/
  901.         }
  902.       }
  903.     } else if (fexist(fconcat(httrack.path_html,"index.html"))) {
  904.       //char s[32];
  905.       httrack.cache=2;  // cache vient aprΦs test de validitΘ
  906.       if (httrack.quiet==0) {
  907.         if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  908.           HT_REQUEST_START;
  909.           HT_PRINT("There is an index.html in the current directory, and a cache"LF);
  910.           HT_PRINT("A site may have been mirrored here, that could mean that you want to update it"LF);
  911.           HT_PRINT("Be sure parameters are ok"LF);
  912.           HT_REQUEST_END;
  913.           if (!ask_continue()) return 0;
  914.         } else {
  915.           HT_REQUEST_START;
  916.           HT_PRINT("There is an index.html in the current directory, but no cache"LF);
  917.           HT_PRINT("A site may have been mirrored here, and erased.."LF);
  918.           HT_PRINT("Be sure parameters are ok"LF);
  919.           HT_REQUEST_END;
  920.           if (!ask_continue()) return 0;
  921.         }
  922.       }
  923.     }
  924.   }
  925.   
  926.   
  927.   // Treat parameters
  928.   // Traiter les paramΦtres
  929. #if DEBUG_STEPS
  930.   printf("Analyze parameters\n");
  931. #endif
  932.   { 
  933.     char* com;
  934.     int na;
  935.     
  936.     for(na=1;na<argc;na++) {
  937.  
  938.       if (argv[na][0]=='"') {
  939.         char tempo[HTS_CDLMAXSIZE];
  940.         strcpy(tempo,argv[na]+1);
  941.         if (tempo[strlen(tempo)-1]!='"') {
  942.           char s[HTS_CDLMAXSIZE];
  943.           sprintf(s,"Missing quote in %s",argv[na]);
  944.           HTS_PANIC_PRINTF(s);
  945.           return -1;
  946.         }
  947.         tempo[strlen(tempo)-1]='\0';
  948.         strcpy(argv[na],tempo);
  949.       }
  950.  
  951.       if (cmdl_opt(argv[na])) { // option
  952.         com=argv[na]+1;
  953.         
  954.         while(*com) {
  955.           switch(*com) {
  956.           case ' ': case 9: case '-': case '\0': break;
  957.             //
  958.           case 'h': help(argv[0],0); return 0;   // dΘja fait normalement
  959.             //
  960.           case 'g':    // rΘcupΘrer un (ou plusieurs) fichiers isolΘs
  961.             httrack.wizard=2;             // le wizard on peut plus s'en passer..
  962.             //httrack.wizard=0;             // pas de wizard
  963.             httrack.cache=0;              // ni de cache
  964.             httrack.makeindex=0;          // ni d'index
  965.             httrack_logmode=1;            // erreurs α l'Θcran
  966.             httrack.savename_type=1003;   // mettre dans le rΘpertoire courant
  967.             httrack.depth=0;              // ne pas explorer la page
  968.             break;
  969.           case 'w': httrack.wizard=2;    // wizard 'soft' (ne pose pas de questions)
  970.             httrack.travel=0;
  971.             httrack.seeker=1;
  972.             break;
  973.           case 'W': httrack.wizard=1;    // Wizard-Help (pose des questions)
  974.             httrack.travel=0;
  975.             httrack.seeker=1;
  976.             break;
  977.           case 'r':                      // n'est plus le recurse get bestial mais wizard itou!
  978.             if (isdigit((unsigned char)*(com+1))) {
  979.               sscanf(com+1,"%d",&httrack.depth);
  980.               while(isdigit((unsigned char)*(com+1))) com++;
  981.             } else httrack.depth=3;
  982.             break;
  983. /*
  984.           case 'r': httrack.wizard=0;
  985.             if (isdigit((unsigned char)*(com+1))) {
  986.               sscanf(com+1,"%d",&httrack.depth);
  987.               while(isdigit((unsigned char)*(com+1))) com++;
  988.             } else httrack.depth=3;
  989.             break;
  990. */
  991.             //
  992.             // note: les tests httrack.depth sont pour Θviter de faire
  993.             // un miroir du web (:-O) accidentelement ;-)
  994.           case 'a': /*if (httrack.depth==9999) httrack.depth=3;*/
  995.             httrack.travel=0+(httrack.travel&256); break;
  996.           case 'd': /*if (httrack.depth==9999) httrack.depth=3;*/
  997.             httrack.travel=1+(httrack.travel&256); break;
  998.           case 'l': /*if (httrack.depth==9999) httrack.depth=3;*/
  999.             httrack.travel=2+(httrack.travel&256); break;
  1000.           case 'e': /*if (httrack.depth==9999) httrack.depth=3;*/
  1001.             httrack.travel=7+(httrack.travel&256); break;
  1002.           case 't': httrack.travel|=256; break;
  1003.           case 'n': httrack.nearlink=1; break;
  1004.           case 'x': httrack.external=1; break;
  1005.             //
  1006.           case 'U': httrack.seeker=2; break;
  1007.           case 'D': httrack.seeker=1; break;
  1008.           case 'S': httrack.seeker=0; break;
  1009.           case 'B': httrack.seeker=3; break;
  1010.             //
  1011.           case 'Y': httrack.mirror_first_page=1; break;
  1012.             //
  1013.           case 'q': case 'i': httrack.quiet=1; break;
  1014.             //
  1015.           case 'Q': httrack_logmode=0; break;
  1016.           case 'v': httrack_logmode=1; break;
  1017.           case 'f': httrack_logmode=2; if (*(com+1)=='2') httrack_logmode=3; while(isdigit((unsigned char)*(com+1))) com++; break;
  1018.             //
  1019.           //case 'A': httrack.urlmode=1; break;
  1020.           //case 'R': httrack.urlmode=2; break;
  1021.           case 'K': httrack.urlmode=0; 
  1022.             if (isdigit(*(com+1))) {
  1023.               sscanf(com+1,"%d",&httrack.urlmode);
  1024.               if (httrack.urlmode == 0)   // in fact K0 ==> K2
  1025.                                           // and K ==> K0
  1026.                 httrack.urlmode=2;
  1027.               while(isdigit((unsigned char)*(com+1))) com++; 
  1028.             }
  1029.             //if (*(com+1)=='0') { httrack.urlmode=2; com++; } break;
  1030.             //
  1031.           case 'c':
  1032.             if (isdigit((unsigned char)*(com+1))) {
  1033.               sscanf(com+1,"%d",&httrack.maxsoc);
  1034.               while(isdigit((unsigned char)*(com+1))) com++;
  1035.               httrack.maxsoc=max(httrack.maxsoc,1);     // FORCER A 1
  1036.             } else httrack.maxsoc=8;
  1037.             
  1038.             break;
  1039.             //
  1040.           case 'p': sscanf(com+1,"%d",&httrack.getmode); while(isdigit((unsigned char)*(com+1))) com++; break;
  1041.             //        
  1042.           case 'G': sscanf(com+1,"%d",&httrack.fragment); while(isdigit((unsigned char)*(com+1))) com++; break;
  1043.           case 'M': sscanf(com+1,"%d",&httrack.maxsite); while(isdigit((unsigned char)*(com+1))) com++; break;
  1044.           case 'm': sscanf(com+1,"%d",&httrack.maxfile_nonhtml); while(isdigit((unsigned char)*(com+1))) com++; 
  1045.             if (*(com+1)==',') {
  1046.               com++;
  1047.               sscanf(com+1,"%d",&httrack.maxfile_html); while(isdigit((unsigned char)*(com+1))) com++;
  1048.             } else httrack.maxfile_html=-1;
  1049.             break;
  1050.             //
  1051.           case 'T': sscanf(com+1,"%d",&httrack.timeout); while(isdigit((unsigned char)*(com+1))) com++; break;
  1052.           case 'J': sscanf(com+1,"%d",&httrack.rateout); while(isdigit((unsigned char)*(com+1))) com++; break;
  1053.           case 'R': sscanf(com+1,"%d",&httrack.retry); while(isdigit((unsigned char)*(com+1))) com++; break;
  1054.           case 'E': sscanf(com+1,"%d",&httrack.maxtime); while(isdigit((unsigned char)*(com+1))) com++; break;
  1055.           case 'H': sscanf(com+1,"%d",&httrack.hostcontrol); while(isdigit((unsigned char)*(com+1))) com++; break;
  1056.           case 'A': sscanf(com+1,"%d",&httrack.maxrate); while(isdigit((unsigned char)*(com+1))) com++; break;
  1057.  
  1058.           case 'j': httrack.parsejava=1; if (*(com+1)=='0') { httrack.parsejava=0; com++; } break;
  1059.             //
  1060.           case 'I': httrack.makeindex=1; if (*(com+1)=='0') { httrack.makeindex=0; com++; } break;
  1061.             //
  1062.           case 'X': httrack.delete_old=1; if (*(com+1)=='0') { httrack.delete_old=0; com++; } break;
  1063.             //
  1064.           case 'b': sscanf(com+1,"%d",&httrack.accept_cookie); while(isdigit((unsigned char)*(com+1))) com++; break;
  1065.             //
  1066.           case 'N':
  1067.             if (strcmp(argv[na],"-N")==0) {    // Tout seul
  1068.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {  // erreur
  1069.                 HTS_PANIC_PRINTF("Option N needs a number, or needs to be followed by a blank space, and a string");
  1070.                 printf("Example: -N4\n");
  1071.                 return -1;
  1072.               } else {
  1073.                 na++;
  1074.                 if (strlen(argv[na])>=127) {
  1075.                   HTS_PANIC_PRINTF("Userdef structure string too long");
  1076.                   return -1;
  1077.                 }
  1078.                 strcpy(httrack.savename_userdef,argv[na]);
  1079.                 if (strnotempty(httrack.savename_userdef))
  1080.                   httrack.savename_type = -1;    // userdef!
  1081.                 else
  1082.                   httrack.savename_type = 0;    // -N "" : par dΘfaut
  1083.               }
  1084.             } else {
  1085.               sscanf(com+1,"%d",&httrack.savename_type); while(isdigit((unsigned char)*(com+1))) com++;
  1086.             }
  1087.             break;
  1088.           case 'L': sscanf(com+1,"%d",&httrack.savename_83); httrack.savename_83=!httrack.savename_83; while(isdigit((unsigned char)*(com+1))) com++; break;
  1089.           case 's': 
  1090.             if (isdigit((unsigned char)*(com+1))) {
  1091.               sscanf(com+1,"%d",&httrack.robots);
  1092.               while(isdigit((unsigned char)*(com+1))) com++;
  1093.             } else httrack.robots=1;
  1094. #if DEBUG_ROBOTS
  1095.             printf("robots.txt mode set to %d\n",httrack.robots);
  1096. #endif
  1097.             break;
  1098.           case 'o': sscanf(com+1,"%d",&httrack.errpage); while(isdigit((unsigned char)*(com+1))) com++; break;
  1099.           case 'u': sscanf(com+1,"%d",&httrack.check_type); while(isdigit((unsigned char)*(com+1))) com++; break;
  1100.             //
  1101.           case 'C': 
  1102.             if (isdigit((unsigned char)*(com+1))) {
  1103.               sscanf(com+1,"%d",&httrack.cache);
  1104.               while(isdigit((unsigned char)*(com+1))) com++;
  1105.             } else httrack.cache=1;
  1106.             break;
  1107.           case 'k': httrack.all_in_cache=1; break;
  1108.             //
  1109.           case 'z': httrack.debug=1; break;  // petit debug
  1110.           case 'Z': httrack.debug=2; break;  // GROS debug
  1111.             //
  1112.           case '&': case '%': {    // deuxiΦme jeu d'options
  1113.             com++;
  1114.             switch(*com) {
  1115.             case 'x': httrack.passprivacy=1; if (*(com+1)=='0') { httrack.passprivacy=0; com++; } break;   // No passwords in html files
  1116.             case 'I': httrack.kindex=1; if (*(com+1)=='0') { httrack.kindex=0; com++; } break;   // Keyword Index
  1117.             case 'c': sscanf(com+1,"%d",&httrack.maxconn); while(isdigit((unsigned char)*(com+1))) com++; break;
  1118.             case 'e': sscanf(com+1,"%d",&httrack.extdepth); while(isdigit((unsigned char)*(com+1))) com++; break;
  1119.             case 'B': httrack.tolerant=1; if (*(com+1)=='0') { httrack.tolerant=0; com++; } break;   // HTTP/1.0 notamment
  1120.             case 'h': httrack.http10=1; if (*(com+1)=='0') { httrack.http10=0; com++; } break;   // HTTP/1.0
  1121.             case 'f': httrack.ftp_proxy=1; if (*(com+1)=='0') { httrack.ftp_proxy=0; com++; } break;   // proxy http pour ftp
  1122.             case 'P': httrack.parseall=1; if (*(com+1)=='0') { httrack.parseall=0; com++; } break;   // tout parser
  1123.             case 'n': httrack.norecatch=1; if (*(com+1)=='0') { httrack.norecatch=0; com++; } break;   // ne pas reprendre fichiers effacΘs localement
  1124.             case 's': httrack.sizehack=1; if (*(com+1)=='0') { httrack.sizehack=0; com++; } break;   // hack sur content-length
  1125.             case 'v': httrack.verbosedisplay=1; if (*(com+1)=='0') { httrack.verbosedisplay=0; com++; } break;
  1126.             case 'L':    // URL list
  1127.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1128.                 HTS_PANIC_PRINTF("Option %L needs to be followed by a blank space, and a text filename");
  1129.                 printf("Example: -%%L \"mylist.txt\"\n");
  1130.                 return -1;
  1131.               } else{
  1132.                 na++;
  1133.                 if (strlen(argv[na])>=254) {
  1134.                   HTS_PANIC_PRINTF("File list string too long");
  1135.                   return -1;
  1136.                 }
  1137.                 strcpy(httrack.filelist,argv[na]);
  1138.               }
  1139.               break;
  1140.               //
  1141.             case 'l': 
  1142.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1143.                 HTS_PANIC_PRINTF("Option %l needs to be followed by a blank space, and an ISO language code");
  1144.                 printf("Example: -%%l \"en\"\n");
  1145.                 return -1;
  1146.               } else{
  1147.                 na++;
  1148.                 if (strlen(argv[na])>=62) {
  1149.                   HTS_PANIC_PRINTF("Lang list string too long");
  1150.                   return -1;
  1151.                 }
  1152.                 strcpy(httrack.lang_iso,argv[na]);
  1153.               }
  1154.               break;
  1155.               //
  1156.             case 'F':     // footer id
  1157.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1158.                 HTS_PANIC_PRINTF("Option %F needs to be followed by a blank space, and a footer string");
  1159.                 printf("Example: -%%F \"<!-- Mirrored from %%s by HTTrack Website Copier/"HTTRACK_AFF_VERSION" "HTTRACK_AFF_AUTHORS" -->\"\n");
  1160.                 return -1;
  1161.               } else{
  1162.                 na++;
  1163.                 if (strlen(argv[na])>=254) {
  1164.                   HTS_PANIC_PRINTF("Footer string too long");
  1165.                   return -1;
  1166.                 }
  1167.                 strcpy(httrack.footer,argv[na]);
  1168.               }
  1169.               break;
  1170.             case 'H':                 // debug headers
  1171.               _DEBUG_HEAD=1;
  1172.               break;
  1173.               /*
  1174.             case 'O':
  1175. #if HTS_WIN
  1176.               printf("Warning option -%%O has no effect in this system (chroot)\n");
  1177. #else
  1178.               switch_chroot=1;
  1179. #endif
  1180.               break;
  1181.               */
  1182.             case 'U':                 // setuid
  1183.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1184.                 HTS_PANIC_PRINTF("Option %U needs to be followed by a blank space, and a username");
  1185.                 printf("Example: -%%U smith\n");
  1186.                 return -1;
  1187.               } else {
  1188.                 na++;
  1189. #if HTS_WIN
  1190.                 printf("Warning option -%%U has no effect on this system (setuid)\n");
  1191. #else
  1192. #ifndef HTS_DO_NOT_USE_UID
  1193.                 /* Change the user id and gid */
  1194.                 {
  1195.                   struct passwd* userdef=getpwnam((const char*)argv[na]);
  1196.                   if (userdef) {    /* we'll have to switch the user id */
  1197.                     switch_gid=userdef->pw_gid;
  1198.                     switch_uid=userdef->pw_uid;
  1199.                   }
  1200.                 }
  1201. #else
  1202.                 printf("Warning option -%%U has no effect with this compiled version (setuid)\n");
  1203. #endif
  1204. #endif
  1205.               }
  1206.               break;
  1207.             }
  1208.                     }
  1209.             break;
  1210.             //
  1211.           case '#':  { // non documentΘ (appel de l'interface)
  1212.             com++;
  1213.             switch(*com) {
  1214.             case 'f': httrack.flush=1; break;
  1215.             case 'h':
  1216.               printf("HTTrack version "HTTRACK_VERSION"\n");
  1217.               exit(1);
  1218.               break;
  1219.             case 'p': httrack.aff_progress=1; break;
  1220.             case 'S': httrack.shell=1; break;  // stdin sur un shell
  1221.             case 'K': httrack.keyboard=1; break;  // vΘrifier stdin
  1222.               //
  1223.             case 'L': sscanf(com+1,"%d",&httrack.maxlink); while(isdigit((unsigned char)*(com+1))) com++; break;
  1224.             case 'F': sscanf(com+1,"%d",&httrack.maxfilter); while(isdigit((unsigned char)*(com+1))) com++; break;
  1225.             case 'Z': httrack.makestat=1; break;
  1226.             case 'T': httrack.maketrack=1; break;
  1227.             case 'u': sscanf(com+1,"%d",&httrack.waittime); while(isdigit((unsigned char)*(com+1))) com++; break;
  1228.               
  1229.             case 'R':    // ohh ftp, catch->ftpget
  1230.               HTS_PANIC_PRINTF("Unexpected internal error with -#R command");
  1231.               return -1;        
  1232.               break;
  1233.             case 'P': {     // catchurl
  1234.               help_catchurl(httrack.path_log);
  1235.               return 0;
  1236.                       }
  1237.               break;
  1238.           
  1239.             case '0':   /* test #0 : filters */
  1240.               if (na+2>=argc) {
  1241.                 HTS_PANIC_PRINTF("Option #0 needs to be followed by a filter string and a string");
  1242.                 printf("Example: '-#0' '*.gif' 'foo.gif'\n");
  1243.                 return -1;
  1244.               } else {
  1245.                 if (strjoker(argv[na+2],argv[na+1],NULL,NULL))
  1246.                   printf("%s does match %s\n",argv[na+2],argv[na+1]);
  1247.                 else
  1248.                   printf("%s does NOT match %s\n",argv[na+2],argv[na+1]);
  1249.                 return 0;
  1250.               }
  1251.               break;
  1252.             case '!':
  1253.               if (na+1>=argc) {
  1254.                 HTS_PANIC_PRINTF("Option #! needs to be followed by a commandline");
  1255.                 printf("Example: '-#!' 'echo hello'\n");
  1256.                 return -1;
  1257.               } else {
  1258.                 system(argv[na+1]);
  1259.               }
  1260.               break;
  1261.  
  1262.             default: printf("Internal option %c not recognized\n",*com); break;
  1263.             }
  1264.                      }
  1265.             break; 
  1266.           case 'O':    // output path
  1267.             na++;     // sauter, dΘja traitΘ
  1268.             break;
  1269.           case 'P':    // proxy
  1270.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1271.               HTS_PANIC_PRINTF("Option P needs to be followed by a blank space, and a proxy proxy:port or user:id@proxy:port");
  1272.               printf("Example: -P proxy.myhost.com:8080\n");
  1273.               return -1;
  1274.             } else {
  1275.               char* a;
  1276.               na++;
  1277.               httrack.proxy.active=1;
  1278.               // Rechercher MAIS en partant de la fin α cause de user:pass@proxy:port
  1279.               a = argv[na] + strlen(argv[na]) -1;
  1280.               // a=strstr(argv[na],":");  // port
  1281.               while( ((int) a > (int) argv[na]) && (*a != ':') && (*a != '@') ) a--;
  1282.               if (*a == ':') {  // un port est prΘsent, <proxy>:port
  1283.                 sscanf(a+1,"%d",&httrack.proxy.port);
  1284.                 httrack.proxy.name[0]='\0';
  1285.                 strncat(httrack.proxy.name,argv[na],(int) a-(int) argv[na]);
  1286.               } else {  // <proxy>
  1287.                 httrack.proxy.port=8080;
  1288.                 strcpy(httrack.proxy.name,argv[na]);
  1289.               }
  1290.             }
  1291.             break;
  1292.           case 'F':    // user-agent field
  1293.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1294.               HTS_PANIC_PRINTF("Option F needs to be followed by a blank space, and a user-agent name");
  1295.               printf("Example: -F \"my_user_agent/1.0\"\n");
  1296.               return -1;
  1297.             } else{
  1298.               na++;
  1299.               if (strlen(argv[na])>=126) {
  1300.                 HTS_PANIC_PRINTF("User-agent length too long");
  1301.                 return -1;
  1302.               }
  1303.               strcpy(httrack.user_agent,argv[na]);
  1304.               if (strnotempty(httrack.user_agent))
  1305.                 httrack.user_agent_send=1;
  1306.               else
  1307.                 httrack.user_agent_send=0;    // -F "" dΘsactive l'option
  1308.             }
  1309.             break;
  1310.             //
  1311.           case 'V':    // execute command
  1312.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1313.               HTS_PANIC_PRINTF("Option V needs to be followed by a system-command string");
  1314.               printf("Example: -V \"tar uvf some.tar \\$0\"\n");
  1315.               return -1;
  1316.             } else{
  1317.               na++;
  1318.               if (strlen(argv[na])>=2048) {
  1319.                 HTS_PANIC_PRINTF("System-command length too long");
  1320.                 return -1;
  1321.               }
  1322.               strcpy(httrack.sys_com,argv[na]);
  1323.               if (strnotempty(httrack.sys_com))
  1324.                 httrack.sys_com_exec=1;
  1325.               else
  1326.                 httrack.sys_com_exec=0;    // -V "" dΘsactive l'option
  1327.             }
  1328.             break;
  1329.             //
  1330.           default: {
  1331.             char s[HTS_CDLMAXSIZE];
  1332.             sprintf(s,"invalid option %c\n",*com);
  1333.             HTS_PANIC_PRINTF(s);
  1334.             return -1;
  1335.                    }
  1336.             break;
  1337.           }  // switch
  1338.           com++;    
  1339.         }  // while
  1340.         
  1341.       }  else {  // URL/filters
  1342.         char* a=argv[na];
  1343.         
  1344.         while(is_space(*a)) a++;
  1345.         
  1346.         // ajouter URLs et filters[]
  1347.         while (*a) {
  1348.           char c[2];
  1349.           c[1]='\0';
  1350.           while(is_space(*a)) a++;
  1351.           if (*a) {
  1352.             if (strnotempty(url)) strcat(url," ");  // espace de sΘparation
  1353.             while((!is_space(*a)) && (*a!=0)) { c[0]=*a; strcat(url,c); a++;}
  1354.           }
  1355.         }    
  1356.         
  1357.         
  1358.       }  // if argv=- etc. 
  1359.       
  1360.     }  // for
  1361.   }
  1362.   
  1363. #if BDEBUG==3  
  1364.   printf("URLs/filters=%s\n",url);
  1365. #endif
  1366.  
  1367. #if DEBUG_STEPS
  1368.   printf("Analyzing parameters done\n");
  1369. #endif
  1370.  
  1371.  
  1372. #if HTS_WIN
  1373. #else
  1374. #ifndef HTS_DO_NOT_USE_UID
  1375.   /* Chroot - xxc */
  1376.   if (switch_chroot) {
  1377.     uid_t userid=getuid();
  1378.     //struct passwd* userdef=getpwuid(userid);
  1379.     //if (userdef) {
  1380.     if (!userid) {
  1381.       //if (strcmp(userdef->pw_name,"root")==0) {
  1382.       char rpath[1024];
  1383.       //printf("html=%s log=%s\n",httrack.path_html,httrack.path_log);    // xxc
  1384.       if ((httrack.path_html[0]) && (httrack.path_log[0])) {
  1385.         char *a=httrack.path_html,*b=httrack.path_log,*c=NULL,*d=NULL;
  1386.         c=a; d=b;
  1387.         while ((*a) && (*a == *b)) {
  1388.           if (*a=='/') { c=a; d=b; }
  1389.           a++;
  1390.           b++;
  1391.         }
  1392.  
  1393.         rpath[0]='\0';
  1394.         if (c != httrack.path_html) {
  1395.           if (httrack.path_html[0]!='/')
  1396.             strcat(rpath,"./");
  1397.           strncat(rpath,httrack.path_html,(int) c - (int) httrack.path_html);
  1398.         }
  1399.         {
  1400.           char tmp[1024];
  1401.           strcpy(tmp,c); strcpy(httrack.path_html,tmp);
  1402.           strcpy(tmp,d); strcpy(httrack.path_log,tmp);
  1403.         }
  1404.       } else {
  1405.         strcpy(rpath,"./");
  1406.         strcpy(httrack.path_html,"/");
  1407.         strcpy(httrack.path_log,"/");
  1408.       }
  1409.       if (rpath[0]) {
  1410.         printf("[changing root path to %s (path_data=%s,path_log=%s)]\n",rpath,httrack.path_html,httrack.path_log);
  1411.         if (chroot(rpath)) {
  1412.           printf("ERROR! Can not chroot to %s!\n",rpath);
  1413.           exit(0);
  1414.         }
  1415.         if (chdir("/")) {     /* new root */
  1416.           printf("ERROR! Can not chdir to %s!\n",rpath);
  1417.           exit(0);
  1418.         }
  1419.       } else
  1420.         printf("WARNING: chroot not possible with these paths\n");
  1421.     }
  1422.     //}
  1423.   }
  1424.  
  1425.   /* Setuid */
  1426.   if (switch_uid>=0) {
  1427.     printf("[setting user/group to %d/%d]\n",switch_uid,switch_gid);
  1428.     if (setgid(switch_gid))
  1429.       printf("WARNING! Can not setgid to %d!\n",switch_gid);
  1430.     if (setuid(switch_uid))
  1431.       printf("WARNING! Can not setuid to %d!\n",switch_uid);
  1432.   }
  1433.  
  1434.   /* Final check */
  1435.   {
  1436.     uid_t userid=getuid();
  1437.     if (!userid) {              /* running as r00t */
  1438.       printf("WARNING! You are running this program as root!\n");
  1439.       printf("It might be a good idea to use the -%%U option to change the userid:\n");
  1440.       printf("Example: -%%U smith\n\n");
  1441.     }
  1442.   }
  1443. #endif
  1444. #endif
  1445.   
  1446.   //printf("WARNING! This is *only* a beta-release of HTTrack\n");
  1447.   io_flush;
  1448.   
  1449. #if DEBUG_STEPS
  1450.   printf("Cache & log settings\n");
  1451. #endif
  1452.   
  1453.   // on utilise le cache..
  1454.   // en cas de prΘsence des deux versions, garder la version la plus avancΘe,
  1455.   // cad la version contenant le plus de fichiers  
  1456.   if (httrack.cache) {
  1457.     if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {   // problemes..
  1458.       if (fexist(fconcat(httrack.path_log,"hts-cache/new.dat")) && fexist(fconcat(httrack.path_log,"hts-cache/new.ndx"))) { 
  1459.         if (fexist(fconcat(httrack.path_log,"hts-cache/old.dat")) && fexist(fconcat(httrack.path_log,"hts-cache/old.ndx"))) {
  1460.           // switcher si new<32Ko et old>65Ko (tailles arbitraires) ?
  1461.           // ce cas est peut Ωtre une erreur ou un crash d'un miroir ancien, prendre
  1462.           // alors l'ancien cache
  1463.           if (fsize(fconcat(httrack.path_log,"hts-cache/new.dat"))<32768) {
  1464.             if (fsize(fconcat(httrack.path_log,"hts-cache/old.dat"))>65536) {
  1465.               if (fsize(fconcat(httrack.path_log,"hts-cache/old.dat")) > fsize(fconcat(httrack.path_log,"hts-cache/new.dat"))) {
  1466.                 remove(fconcat(httrack.path_log,"hts-cache/new.dat"));
  1467.                 remove(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  1468.                 rename(fconcat(httrack.path_log,"hts-cache/old.dat"),fconcat(httrack.path_log,"hts-cache/new.dat"));
  1469.                 rename(fconcat(httrack.path_log,"hts-cache/old.ndx"),fconcat(httrack.path_log,"hts-cache/new.ndx"));  
  1470.                 //} else {  // ne rien faire
  1471.                 //  remove("hts-cache/old.dat");
  1472.                 //  remove("hts-cache/old.ndx");
  1473.               }
  1474.             }
  1475.           }
  1476.         }
  1477.       }
  1478.     }
  1479.   }
  1480.  
  1481.   // DΘbuggage des en tΩtes
  1482.   if (_DEBUG_HEAD) {
  1483.     ioinfo=fopen(fconcat(httrack.path_log,"hts-ioinfo.txt"),"wb");
  1484.   }
  1485.   
  1486.   {
  1487.     char n_lock[256];
  1488.     // on peut pas avoir un affichage ET un fichier log
  1489.     // ca sera pour la version 2
  1490.     if (httrack_logmode==1) {
  1491.       httrack.log=stdout;
  1492.       httrack.errlog=stderr;
  1493.     } else if (httrack_logmode>=2) {
  1494.       // deux fichiers log
  1495.       structcheck(httrack.path_log);
  1496.       if (fexist(fconcat(httrack.path_log,"hts-log.txt")))
  1497.         remove(fconcat(httrack.path_log,"hts-log.txt"));
  1498.       if (fexist(fconcat(httrack.path_log,"hts-err.txt")))
  1499.         remove(fconcat(httrack.path_log,"hts-err.txt"));
  1500.  
  1501.       httrack.log=fopen(fconcat(httrack.path_log,"hts-log.txt"),"w");
  1502.       if (httrack_logmode==2)
  1503.         httrack.errlog=fopen(fconcat(httrack.path_log,"hts-err.txt"),"w");
  1504.       else
  1505.         httrack.errlog=httrack.log;
  1506.       if (httrack.log==NULL) {
  1507.         char s[HTS_CDLMAXSIZE];
  1508.         sprintf(s,"Unable to create log file %s",fconcat(httrack.path_log,"hts-log.txt"));
  1509.         HTS_PANIC_PRINTF(s);
  1510.         return -1;
  1511.       } else if (httrack.errlog==NULL) {
  1512.         char s[HTS_CDLMAXSIZE];
  1513.         sprintf(s,"Unable to create log file %s",fconcat(httrack.path_log,"hts-err.txt"));
  1514.         HTS_PANIC_PRINTF(s);
  1515.         return -1;
  1516.       }
  1517.  
  1518.     } else {
  1519.       httrack.log=NULL;
  1520.       httrack.errlog=NULL;
  1521.     }
  1522.     
  1523.     // un petit lock-file pour indiquer un miroir en cours, ainsi qu'un Θventuel fichier log
  1524.     {
  1525.       FILE* fp=NULL;
  1526.       //int n=0;
  1527.       char t[256];
  1528.       time_local_rfc822(t);    // faut bien que ca serve quelque part l'heure RFC1945 arf'
  1529.       
  1530.       /* readme for information purpose */
  1531.       {
  1532.         FILE* fp=fopen(fconcat(httrack.path_log,"hts-cache/readme.txt"),"wb");
  1533.         if (fp) {
  1534.           fprintf(fp,"What's in this folder?"LF);
  1535.           fprintf(fp,""LF);
  1536.           fprintf(fp,"This folder (hts-cache) has been generated by WinHTTrack "HTTRACK_VERSION""LF);
  1537.           fprintf(fp,"and is used for updating this website."LF);
  1538.           fprintf(fp,"(The HTML website structure is stored here to allow fast updates)"LF""LF);
  1539.           fprintf(fp,"DO NOT delete this folder unless you do not want to update the mirror in the future!!"LF);
  1540.           fprintf(fp,"(you can safely delete old.dat, old.ndx and old.lst files, however)"LF);
  1541.           fprintf(fp,""LF);
  1542.           fprintf(fp,HTS_LOG_SECURITY_WARNING);
  1543.           fclose(fp);
  1544.         }
  1545.       }
  1546.  
  1547.       sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress.lock"));
  1548.       //sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress.lock"),n);
  1549.       /*do {
  1550.         if (!n)
  1551.           sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress.lock"),n);
  1552.         else
  1553.           sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress%d.lock"),n);
  1554.         n++;
  1555.       } while((fexist(n_lock)) && httrack.quiet);      
  1556.       if (fexist(n_lock)) {
  1557.         if (!recuperer) {
  1558.           remove(n_lock);
  1559.         }
  1560.       }*/
  1561.  
  1562.       // vΘrifier existence de la structure
  1563.       structcheck(httrack.path_html);
  1564.       structcheck(httrack.path_log);
  1565.      
  1566.       // reprise/update
  1567.       if (httrack.cache) {
  1568.         FILE* fp;
  1569.         int i;
  1570. #if HTS_WIN
  1571.         mkdir(fconcat(httrack.path_log,"hts-cache"));
  1572. #else
  1573.         mkdir(fconcat(httrack.path_log,"hts-cache"),HTS_PROTECT_FOLDER);
  1574. #endif
  1575.         fp=fopen(fconcat(httrack.path_log,"hts-cache/doit.log"),"wb");
  1576.         if (fp) {
  1577.           for(i=0+1;i<argc;i++) {
  1578.             if ( ((strchr(argv[i],' ')!=NULL) || (strchr(argv[i],'"')!=NULL) || (strchr(argv[i],'\\')!=NULL)) && (argv[i][0]!='"')  ) {
  1579.               int j;
  1580.               fprintf(fp,"\"");
  1581.               for(j=0;j<(int) strlen(argv[i]);j++) {
  1582.                 if (argv[i][j]==34)
  1583.                   fprintf(fp,"\\\"");
  1584.                 else if (argv[i][j]=='\\')
  1585.                   fprintf(fp,"\\\\");
  1586.                 else
  1587.                   fprintf(fp,"%c",argv[i][j]);
  1588.               }
  1589.               fprintf(fp,"\"");
  1590.             } else if (strnotempty(argv[i])==0) {   // ""
  1591.               fprintf(fp,"\"\"");
  1592.             } else {   // non critique
  1593.               fprintf(fp,"%s",argv[i]);
  1594.             }
  1595.             if (i<argc-1)
  1596.               fprintf(fp," ");
  1597.           }
  1598.           fprintf(fp,LF);
  1599.           fprintf(fp,"File generated automatically on %s, do NOT edit"LF,t);
  1600.           fprintf(fp,LF);
  1601.           fprintf(fp,"To update a mirror, just launch httrack without any parameters"LF);
  1602.           fprintf(fp,"The existing cache will be used (and modified)"LF);
  1603.           fprintf(fp,"To have other options, retype all parameters and launch HTTrack"LF);
  1604.           fprintf(fp,"To continue an interrupted mirror, just launch httrack without any parameters"LF);
  1605.           fprintf(fp,LF);
  1606.           fclose(fp); fp=NULL;
  1607.         //} else if (httrack.debug>1) {
  1608.         //  printf("! FileOpen error, \"%s\"\n",strerror(errno));
  1609.         }
  1610.       }
  1611.       
  1612.       // petit message dans le lock
  1613.       if ( (fp=fopen(n_lock,"wb"))!=NULL) {
  1614.         int i;
  1615.         fprintf(fp,"Mirror in progress since %s .. please wait!"LF,t);
  1616.         for(i=0;i<argc;i++) {
  1617.           if (strchr(argv[i],' ')==NULL)
  1618.             fprintf(fp,"%s ",argv[i]);
  1619.           else    // entre ""
  1620.             fprintf(fp,"\"%s\" ",argv[i]);
  1621.         }
  1622.         fprintf(fp,LF);
  1623.         fclose(fp); fp=NULL;
  1624.       }
  1625.       
  1626.       // fichier log        
  1627.       if (httrack.log)     {
  1628.         int i;
  1629.         fprintf(httrack.log,"HTTrack"HTTRACK_VERSION" launched on %s at %s"LF,t,url);
  1630.         fprintf(httrack.log,"(");
  1631.         for(i=0;i<argc;i++) {
  1632.           if ((strchr(argv[i],' ')==NULL) || (strchr(argv[i],'\"')))
  1633.             fprintf(httrack.log,"%s ",argv[i]);
  1634.           else    // entre "" (si espace(s) et pas dΘja de ")
  1635.             fprintf(httrack.log,"\"%s\" ",argv[i]);
  1636.         }
  1637.         fprintf(httrack.log,")"LF);
  1638.         fprintf(httrack.log,LF);
  1639.         fprintf(httrack.log,"Information, Warnings and Errors reported for this mirror:"LF);
  1640.         fprintf(httrack.log,HTS_LOG_SECURITY_WARNING );
  1641.         fprintf(httrack.log,LF);
  1642.       }
  1643.  
  1644.       if (httrack_logmode)     {
  1645.         printf("Mirror launched on %s by HTTrack Website Copier/"HTTRACK_VERSION" "HTTRACK_AFF_AUTHORS""LF,t);
  1646.         if (httrack.wizard==0) {
  1647.           printf("mirroring %s with %d levels, %d sockets,t=%d,s=%d,logm=%d,lnk=%d,mdg=%d\n",url,httrack.depth,httrack.maxsoc,httrack.travel,httrack.seeker,httrack_logmode,httrack.urlmode,httrack.getmode);
  1648.         } else {    // the magic wizard
  1649.           printf("mirroring %s with the wizard help..\n",url);
  1650.         }
  1651.       }
  1652.     }
  1653.     
  1654.     io_flush;
  1655.  
  1656. #if HTS_ANALYSTE
  1657.   hts_htmlcheck_init();
  1658. #endif
  1659.  
  1660.   // dΘtourner SIGHUP etc.
  1661. #if HTS_WIN
  1662.   signal( SIGINT  , sig_ask    );   // ^C
  1663.   signal( SIGTERM , sig_finish );   // kill <process>
  1664. #else
  1665.   signal( SIGHUP  , sig_back   );   // close window
  1666.   signal( SIGTSTP , sig_back   );   // ^Z
  1667.   signal( SIGTERM , sig_finish );   // kill <process>
  1668.   signal( SIGINT  , sig_ask    );   // ^C
  1669. /*
  1670. deprecated - see SIGCHLD
  1671. #ifndef HTS_DO_NOT_SIGCLD
  1672.   signal( SIGCLD  , sig_ignore );   // child change status
  1673. #endif
  1674. */
  1675.   signal( SIGCHLD , sig_ignore );   // child change status
  1676. #endif
  1677. #if DEBUG_STEPS
  1678.   printf("Launching the mirror\n");
  1679. #endif
  1680.   
  1681.  
  1682.     // Lancement du miroir
  1683.     // ------------------------------------------------------------
  1684.     if (httpmirror(url,httrack)==0) {
  1685.       printf("Error during operation (see log file), site has not been successfully mirrored\n");
  1686.     } else {
  1687.       if  (httrack.shell) {
  1688.         HTT_REQUEST_START;
  1689.         HT_PRINT("TRANSFER DONE"LF);
  1690.         HTT_REQUEST_END
  1691.       } else {
  1692.         printf("Done.\n");
  1693.       }
  1694.     }
  1695.     // ------------------------------------------------------------
  1696.  
  1697.     if (exit_xh ==1) {
  1698.       if (httrack.log) {
  1699.         fprintf(httrack.log,"* * MIRROR ABORTED! * *\nThe current temporary cache is required for any update operation and only contains data downloaded during the present aborted session.\nThe former cache might contain more complete information; if you do not want to lose that information, you have to restore it and delete the current cache.\nThis can easily be done here by erasing the hts-cache/new.* files]\n");
  1700.       }
  1701.     }
  1702.  
  1703. #if HTS_ANALYSTE
  1704.   hts_htmlcheck_uninit();
  1705. #endif
  1706.     
  1707.     if (httrack_logmode==1) {
  1708.       if (httrack.errlog == httrack.log) httrack.errlog=NULL;
  1709.       if (httrack.log) { fclose(httrack.log); httrack.log=NULL; }
  1710.       if (httrack.errlog) { fclose(httrack.errlog); httrack.errlog=NULL; }
  1711.     }  
  1712.     
  1713.     // DΘbuggage des en tΩtes
  1714.     if (_DEBUG_HEAD) {
  1715.       if (ioinfo) {
  1716.         fclose(ioinfo);
  1717.       }
  1718.     }
  1719.     
  1720.     // supprimer lock
  1721.     remove(n_lock);
  1722.   }
  1723.   
  1724.   if (x_argvblk)
  1725.     freet(x_argvblk);
  1726.  
  1727. #if HTS_WIN
  1728. #if HTS_ANALYSTE!=2
  1729. //  WSACleanup();    // ** non en cas de thread tjs prΘsent!..
  1730. #endif
  1731. #endif
  1732. #if HTS_TRACE_MALLOC
  1733.   hts_freeall();
  1734. #endif
  1735.  
  1736.   printf("Thanks for using HTTrack!\n");
  1737.   io_flush;
  1738.   return 0;    // OK
  1739. }
  1740.  
  1741.  
  1742. // main() subroutines
  1743.  
  1744. // vΘrifier chemin path
  1745. void check_path(char* s) {
  1746.   int i;
  1747.   expand_home(s);         /* expand from ~/ to /home/smith/ */
  1748.   for(i=0;i<(int) strlen(s);i++)    // conversion \ -> /
  1749.     if (s[i]=='\\')
  1750.       s[i]='/';
  1751.   if (s[strlen(s)-1]!='/')    // ajouter slash α la fin
  1752.     strcat(s,"/");
  1753. }
  1754.  
  1755. // dΘtermine si l'argument est une option
  1756. int cmdl_opt(char* s) {
  1757.   if (s[0]=='-') {  // c'est peut Ωtre une option
  1758.     if (strchr(s,'.')!=NULL)
  1759.       return 0;    // sans doute un -www.truc.fr (note: -www n'est pas compris)
  1760.     else if (strchr(s,'/')!=NULL)
  1761.       return 0;    // idem, -*cgi-bin/
  1762.     else if (strchr(s,'*')!=NULL)
  1763.       return 0;    // joker, idem
  1764.     else
  1765.       return 1;
  1766.   } else return 0;
  1767. }
  1768.  
  1769.  
  1770.  
  1771.